package com.fzh.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Netty应答服务器
 * @author ZoharFang
 * @date 2016年8月31日
 */
public class EchoServer {

	private final String host;
	private final int port;

	public EchoServer(String host,int port) {
		this.host = host;
		this.port = port;
	}
	
	public void start() throws Exception {
		//创建一个NioEventLoopGroup实例来 处理事件，如接受新连接、接收数据、写数据等等
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			//创建ServerBootstrap实例来引导绑定和启动服务器
			ServerBootstrap b = new ServerBootstrap();
			
			//指定通道类型为NioServerSocketChannel，设置InetSocketAddress让服务器监听某个端口已等待客户端连接
			b.group(group).channel(NioServerSocketChannel.class).localAddress(host,port)
		     .childHandler(new ChannelInitializer<Channel>() {	//指定连接后调用的ChannelHandler

		    	//实现抽象类ChannelInitializer的initChannel方法来设置ChannelHandler
				@Override
				protected void initChannel(Channel ch) throws Exception {
					ch.pipeline().addLast(new StringDecoder())	//解码器将消息从字节码转成Java对象
					.addLast(new StringEncoder())	//编码器将Java对象转成字节码
					.addLast(new EchoServerHandler());//添加一个ChannelHandler，客户端成功连接服务器后就会被执行
				}
			});
			
			//绑定服务器,sync()方法会阻塞直到服务器完成绑定
			ChannelFuture f = b.bind().sync();
			System.out.println(EchoServer.class.getName() + " started and listen on "
					 + f.channel().localAddress());
			//服务器等待通道关闭，sync()方法也会使关闭操作被阻塞
			f.channel().closeFuture().sync();
		} finally {
			group.shutdownGracefully().sync();
		}
	}
	
	public static void main(String[] args) throws Exception {
		new EchoServer("127.0.0.1", 20000).start();
	}
	
	
	
}
